package com.cpit.platform.web.controller;

import com.cpit.platform.common.entity.Result;
import com.cpit.platform.common.entity.UploadFile;
import com.cpit.platform.common.utils.Encodes;
import com.cpit.platform.common.utils.ResultUtil;
import com.cpit.platform.config.GlobalConfig;
import com.cpit.platform.config.UploadPathConfig;
import com.cpit.platform.log.LogOperator;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

@Controller
@RequestMapping(value = "/file")
public class FileController {

    private final ResourceLoader resourceLoader;

    private static final String loggerName = FileController.class.getName();

    @Autowired
    public FileController(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }

    @Autowired
    private UploadPathConfig uploadPath;

    @Autowired
    private GlobalConfig globalConfig;

    @ApiOperation(value = "导入图片信息", notes = "向系统中导入图片，用于后续浏览。")
    @ResponseBody
    @RequestMapping(value = {"/uploadImage"}, method = RequestMethod.POST, consumes = "multipart/form-data")
    public Result<UploadFile> uploadOne(
            @ApiParam(value = "图片文件信息。", required = true) MultipartFile file) {

        String upload = uploadPath.getTemp();

        File dirFile1 = new File(uploadPath.getTemp());
        if (!dirFile1.exists() && !dirFile1.isDirectory()) {
            dirFile1.mkdirs();
        }

        UploadFile upFile;
//        String[] names = file.getOriginalFilename().split("\\.");
//        String newFileName = names[0] + "_" + new Date().getTime() + "." + names[1];
        int fixPosition = file.getOriginalFilename().lastIndexOf(".");
        String newFileName = file.getOriginalFilename().substring(0, fixPosition)
                + "_" + System.currentTimeMillis() +"."
                + file.getOriginalFilename().substring(fixPosition + 1);

        Path filePath = Paths.get(upload, newFileName);
        upFile = new UploadFile();
        upFile.setUpFileName(newFileName);
        upFile.setDownPath(globalConfig.getContextPath() + "/file/download/temp/" + newFileName);
        upFile.setDeletePath(globalConfig.getContextPath() + "/file/delete/temp/" + newFileName);
        upFile.setServerPath(filePath.toString());
        upFile.setFileSize(file.getSize());

        LogOperator.debug(loggerName, upFile.toString());

        if (!file.isEmpty()) {
            try {
                Files.copy(file.getInputStream(), filePath);
            } catch (IOException | RuntimeException e) {
                LogOperator.err(loggerName, "file upload error!", e);
                return ResultUtil.error(Result.CODE_FAILED, "上传文件失败！");
            }
        } else {
            LogOperator.debug(loggerName, file.getName() + "file is empty!");
            return ResultUtil.error(Result.CODE_FAILED, "上传文件失败，文件为空！");
        }
        return ResultUtil.success(upFile);
    }

    @ApiOperation(value = "导出图片信息", notes = "查询系统图片。")
    @ResponseBody
    @RequestMapping(value = {"/download/{filedir}/{filename:.+}"}, method = RequestMethod.GET)
    public ResponseEntity<?> getFile(
            @ApiParam(value = "文件路径。", required = true) @PathVariable String filedir,
            @ApiParam(value = "文件名称。", required = true) @PathVariable String filename) {

        try {
            String fileDirPath = uploadPath.getPath() + "/" + filedir;
//            if (filedir.equals("temp")) {
//                fileDirPath = uploadPath.getTemp();
//            } else {
//                fileDirPath = uploadPath.getAppeal();
//            }

            Path filePath = Paths.get(fileDirPath, filename);
            FileSystemResource file = new FileSystemResource(filePath.toFile());

            HttpHeaders headers = new HttpHeaders();
            if(isAttechment(filename)) {
                headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
                headers.add("Content-Disposition",
                        String.format("attachment; filename=\"%s\"", java.net.URLEncoder.encode(filename, "UTF-8")));
                headers.add("Pragma", "no-cache");
                headers.add("Expires", "0");
            }
            String medType = getMediaType(filename);
            return ResponseEntity.ok().headers(headers).contentLength(file.contentLength())
                    .contentType(MediaType.parseMediaType(medType))
                    .body(resourceLoader.getResource("file:" + filePath));
        } catch (Exception e) {
            LogOperator.err(loggerName, "download file error!", e);
            return ResponseEntity.notFound().build();
        }
    }

    @ApiOperation(value = "导入图片信息", notes = "向系统中导入图片，用于后续浏览。")
    @ResponseBody
    @RequestMapping(value = {"/upload/temp"}, method = RequestMethod.POST, consumes = "multipart/form-data")
    public Result<List<UploadFile>> upload(
            @ApiParam(value = "图片文件信息。", required = true) MultipartHttpServletRequest request) {

        String upload = uploadPath.getTemp();

        File dirFile1 = new File(uploadPath.getTemp());
        if (!dirFile1.exists() && !dirFile1.isDirectory()) {
            dirFile1.mkdirs();
        }

        List<MultipartFile> files = request.getFiles("file");
        List<UploadFile> upFiles = new ArrayList<UploadFile>();

        UploadFile upFile;

        for (MultipartFile file : files) {

//            String[] names = file.getOriginalFilename().split("\\.");
//            String newFileName = names[0] + "_" + new Date().getTime() + "." + names[1];
            int fixPosition = file.getOriginalFilename().lastIndexOf(".");
            String newFileName = file.getOriginalFilename().substring(0, fixPosition)
                    + "_" + System.currentTimeMillis() +"."
                    + file.getOriginalFilename().substring(fixPosition + 1);

            Path filePath = Paths.get(upload, newFileName);

            upFile = new UploadFile();
            upFile.setUpFileName(file.getOriginalFilename());
            upFile.setDownPath(globalConfig.getContextPath() + "/file/download/temp/" + newFileName);
            upFile.setDeletePath(globalConfig.getContextPath() + "/file/delete/temp/" + newFileName);
            upFile.setServerPath(filePath.toString());
            upFile.setFileSize(file.getSize());

            LogOperator.debug(loggerName, upFile.toString());

            if (!file.isEmpty()) {
                try {
                    Files.copy(file.getInputStream(), filePath);
                } catch (IOException | RuntimeException e) {
                    LogOperator.err(loggerName, "file upload error!", e);
                    return ResultUtil.error("1", "上传文件失败！");
                }
            } else {
                LogOperator.debug(loggerName, file.getName() + "file is empty!");
                return ResultUtil.error("1", "上传文件失败，文件为空！");
            }

            upFiles.add(upFile);
        }

        return ResultUtil.success(upFiles);
    }

    @ApiOperation(value = "删除文件信息", notes = "删除文件信息。")
    @ResponseBody
    @RequestMapping(value = {"/delete/temp/{filename:.+}"}, method = RequestMethod.DELETE)
    public Result<Integer> deleteFile(@ApiParam(value = "文件名称。", required = true) @PathVariable String filename) {
        try {
            Files.delete(Paths.get(uploadPath.getTemp(), filename));
        } catch (IOException e) {
            LogOperator.err(loggerName, "delete file error!", e);
            return ResultUtil.error("1", "删除文件失败！");
        }
        return ResultUtil.success();
    }


    @ApiOperation(value = "删除文件,文件路径及文件名为base64编码", notes = "删除文件信息。")
    @ResponseBody
    @RequestMapping(value = {"/delete64/{path}"}, method = RequestMethod.DELETE)
    public Result<Integer> deleteBase64File(@ApiParam(value = "文件名称。", required = true) @PathVariable String path) {
        try {
            Files.delete(Paths.get(Encodes.decodeBase64String(path)));
        } catch (IOException e) {
            LogOperator.err(loggerName, "delete file error!", e);
            return ResultUtil.error("1", "删除文件失败！");
        }
        return ResultUtil.success();
    }


    @ApiOperation(value = "下载文件，文件路径及文件名为base64编码", notes = "下载文件。")
    @ResponseBody
    @RequestMapping(value = {"/download64/**/{path}"}, method = RequestMethod.GET)
    public ResponseEntity<?> getBase64File(
            @ApiParam(value = "文件路径及名称。", required = true) @PathVariable String path, HttpServletRequest request) {

        try {

            path = request.getServletPath().substring(request.getServletPath().lastIndexOf("download64/") + 11);
            String fileDirPath = Encodes.decodeBase64String(path);

            Path filePath = Paths.get(fileDirPath);
            FileSystemResource file = new FileSystemResource(filePath.toFile());

            String fileName = fileDirPath.substring(fileDirPath.lastIndexOf("/") + 1);

            HttpHeaders headers = new HttpHeaders();
            headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
            headers.add("Content-Disposition",
                    String.format("attachment; filename=\"%s\"", java.net.URLEncoder.encode(fileName, "UTF-8")));
            headers.add("Pragma", "no-cache");
            headers.add("Expires", "0");

            return ResponseEntity.ok().headers(headers).contentLength(file.contentLength())
                    .contentType(MediaType.parseMediaType("application/octet-stream"))
                    .body(resourceLoader.getResource("file:" + filePath));
        } catch (Exception e) {
            LogOperator.err(loggerName, "download file error!", e);
            return ResponseEntity.notFound().build();
        }
    }

    protected String getMediaType(String fileName) {
        if(fileName.endsWith("swf") || fileName.endsWith("fla")) {
            return "application/x-shockwave-flash";
        } else if(fileName.endsWith("png")) {
            return "image/png";
        } else if(fileName.endsWith("jpg")) {
            return "image/jpeg";
        } else if(fileName.endsWith("mp4")) {
            return "video/mp4";
        } else {
            return "application/octet-stream";
        }
    }

    protected boolean isAttechment(String fileName) {
        if(fileName.endsWith("swf") || fileName.endsWith("fla") || fileName.endsWith("mp4")) {
            return false;
        } else {
            return true;
        }
    }

}
